package com.mapforge.selection;

import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class CompositeContinuousSelection implements Selection {
	private Rectangle boundingRectangle;
	private List<ContinuousSelection> selection;

	public CompositeContinuousSelection() {
		boundingRectangle = new Rectangle();
		selection = new ArrayList<ContinuousSelection>();
	}

	public Rectangle getBoundingRectangle() {
		return boundingRectangle;
	}

	@Override
	public void setOrigin(int x, int y) {
		// TODO Auto-generated method stub

	}

	@Override
	public Iterator<ComparablePoint> iterator() {
		return new MultiRectIterator();
	}

	@Override
	public Iterator<ComparablePoint> iterator(Rectangle rectangle) {
		return new MultiRectIterator(rectangle);
	}

	@Override
	public void clearSelection() {
		boundingRectangle.setFrame(0, 0, 0, 0);
		selection.clear();
	}

	@Override
	public boolean add(Selection other) {
		if (other instanceof ContinuousSelection) {
			selection.add((ContinuousSelection) other);
			return true;
		} else {
			throw new IllegalArgumentException(
					"Cannot add anything but Continous Selections.");
		}
	}

	@Override
	public boolean subtract(Selection other) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean intersect(Selection other) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean contains(int x, int y) {
		for (Selection rect : selection) {
			if (rect.contains(x, y)) {
				return true;
			}
		}
		return false;
	}

	private class MultiRectIterator implements Iterator<ComparablePoint> {
		int pos;
		Iterator<ComparablePoint> it;
		Rectangle intersection;

		public MultiRectIterator() {
			this(null);
		}

		public MultiRectIterator(Rectangle r) {
			pos = 0;
			this.intersection = r;
			if (r != null) {
				it = new RectangularIterator(selection.get(0)
						.getBoundingRectangle().intersection(intersection));
			} else {
				it = new RectangularIterator(selection.get(0)
						.getBoundingRectangle());
			}
		}

		public boolean hasNext() {
			if (it.hasNext()) {
				return true;
			} else {
				pos++;
				if (pos < selection.size()) {
					Rectangle rect = selection.get(pos).getBoundingRectangle();
					if (intersection != null) {
						// skip all selections this doesn't intersect
						while (!rect.intersects(intersection)
								&& pos < selection.size()) {
							pos++;
							rect = selection.get(pos).getBoundingRectangle();
						}
						// nothing intersects
						if (pos > selection.size()) {
							return false;
						}
						it = new RectangularIterator(
								rect.intersection(intersection));
					}
					// null intersection, just grab next
					else {
						it = selection.get(pos).iterator();
					}
					return true;
				} else {
					return false;
				}
			}
		}

		@Override
		public ComparablePoint next() {
			return it.next();
		}

		@Override
		public void remove() {
			throw new IllegalArgumentException("Cannot remove points.");
		}
	}

	@Override
	public Selection addition(Selection other) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Selection subtraction(Selection other) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Selection intersection(Selection other) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public boolean intersects(Selection other) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean isEmpty() {
		// TODO Auto-generated method stub
		return false;
	}
}
